package com.lemon.stock.compose

import android.annotation.SuppressLint
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.KeyboardArrowLeft
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.google.accompanist.coil.rememberCoilPainter
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.rememberPagerState
import com.lemon.stock.R
import com.lemon.stock.app.StockHandleType
import com.lemon.stock.entity.Stock
import com.lemon.stock.entity.Trade
import com.lemon.stock.entity.TradeDeleteState
import com.lemon.stock.theme.*
import com.lemon.stock.viewmodel.StocksViewModel
import com.lemon.stock.viewmodel.TradeViewModel
import java.text.SimpleDateFormat
import java.util.*

/**
 * 股票详情：含新增股票
 */
@ExperimentalPagerApi
@Composable
fun StockScreen(stockIDs: Array<String>, currentIndex: Int, onback: ()->Unit){
    var stockId: String? = ""
    if(currentIndex >=0){
        stockId = stockIDs[currentIndex]
    }
    val stockState = rememberSaveable{ mutableStateOf(stockId)}
    Crossfade(stockState.value?:"") {stockId->
        if(stockId == ""){
            StockCreateScreen(stockState, onback)
        }else{
            val pagerState = rememberPagerState(pageCount = stockIDs.size, initialPage =currentIndex)
            HorizontalPager(state = pagerState, modifier = Modifier.padding(0.dp)) {
                val id = (stockIDs[currentPage]).substring(2)
                StockDetailScreen(id, onback)
            }
        }
    }
}

/**
 * 新增股票
 * TopAppBar
 */
@Composable
fun StockCreateScreen(stockState: MutableState<String?>, onback: ()->Unit){
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("股票") },
                elevation = 8.dp,
                navigationIcon = {
                    IconButton(onClick = onback) {
                        Icon(Icons.Filled.ArrowBack, contentDescription = null)
                    }
                }
            )
        }
    ) {
        Column(modifier = Modifier.fillMaxSize()) {
            CreateStockContent(stockState)
        }
    }
}

/**
 * 新增股票
 * 输入股票代码，从新浪开放的接口中查询相关数据，保存后转到股票详情
 */
@Composable
fun CreateStockContent(stockState: MutableState<String?>){
    val mViewModel: StocksViewModel = viewModel()
    val oStock = mViewModel.remote.observeAsState()
    stockState.value = oStock.value
    var stockId by remember { mutableStateOf(TextFieldValue()) }
    val context = LocalContext.current

    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
    ) {
        val strCaption = context.getResources().getString(R.string.caption_stock)
        item {
            InputItem(
                textFieldValue = stockId,
                label = strCaption+stringResource(id = R.string.stock_id),
                onTextChanged = { stockId = it },
                modifier = Modifier
                    .fillMaxSize()
                    .padding(vertical = 4.dp)
            )
        }
        item {
            Button(
                onClick = {
                    val sid = stockId.text
                    mViewModel.remoteStock(sid)
                },
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(vertical = 8.dp)
            ) {
                Text(
                    text = stringResource(id = R.string.btn_fetch),
                    color = MaterialTheme.colors.onPrimary,
                    modifier = Modifier.padding(horizontal = 30.dp, vertical = 8.dp)
                )
            }
        }
    }
}

/**
 * 股票详情
 * TopAppBar和底部按钮组
 */
@Composable
fun StockDetailScreen(stockId: String, onback: ()->Unit){
    val handleStatus = rememberSaveable {mutableStateOf(StockHandleType.Detail)}

    val mViewModel: StocksViewModel = viewModel()
    val oStock = mViewModel.stock.observeAsState()
    mViewModel.fetchStock(stockId)
    var vStock = oStock.value
    if(vStock!=null){
        Scaffold(
            topBar = {
                if(handleStatus.value == StockHandleType.Detail){
                    TopAppBar(
                        title = {
                            Column(
                                horizontalAlignment = Alignment.CenterHorizontally,
                                modifier = Modifier
                                    .padding(end = 20.dp)
                                    .fillMaxWidth()
                            ) {
                                Text(text = vStock.stockName)
                                Text(text = vStock.stockId, fontSize = 14.sp)
                            }
                        },
                        navigationIcon = {
                            IconButton(onClick = onback) {
                                Icon(Icons.Filled.KeyboardArrowLeft, contentDescription = null)
                            }
                        }
                    )
                }else{
                    val titleName = when(handleStatus.value){
                        StockHandleType.Buy -> stringResource(R.string.btn_buy)+ vStock.stockName
                        StockHandleType.Sell -> stringResource(R.string.btn_sell)+ vStock.stockName
                        StockHandleType.Bonus -> vStock.stockName + stringResource(R.string.btn_bonus)
                        StockHandleType.Line -> vStock.stockName
                        else->vStock.stockName
                    }
                    TopAppBar(
                        title = {
                            Column(
                                horizontalAlignment = Alignment.CenterHorizontally,
                                modifier = Modifier
                                    .padding(start = 0.dp)
                                    .fillMaxWidth()
                            ) {
                                Text(text = titleName)
                            }
                        }
                    )
                }
            },
            bottomBar = {
                /**底部按钮组**/
                if(handleStatus.value == StockHandleType.Detail){
                    BottomAppBar(
                        backgroundColor = Color.White
                    ) {
                        Button(
                            colors = ButtonDefaults.buttonColors(
                                backgroundColor = green700, contentColor = Color.White
                            ),
                            onClick = {handleStatus.value = StockHandleType.Buy },
                            modifier = Modifier.padding(8.dp),
                            elevation = ButtonDefaults.elevation()
                        ) {
                            Text(text = stringResource(R.string.btn_buy))
                        }
                        Button(
                            colors = ButtonDefaults.buttonColors(
                                backgroundColor = blue700,
                                contentColor = Color.White
                            ),
                            onClick = { handleStatus.value = StockHandleType.Sell },
                            modifier = Modifier.padding(8.dp),
                            elevation = ButtonDefaults.elevation()
                        ) {
                            Text(text = stringResource(R.string.btn_sell))
                        }
                        Button(
                            colors = ButtonDefaults.buttonColors(
                                backgroundColor = red700,
                                contentColor = Color.White
                            ),
                            onClick = {
                                handleStatus.value = StockHandleType.Bonus
                            },
                            modifier = Modifier.padding(8.dp),
                            elevation = ButtonDefaults.elevation()
                        ) {
                            Text(text = stringResource(R.string.btn_bonus))
                        }
                        Button(
                            colors = ButtonDefaults.buttonColors(
                                backgroundColor = purple700,
                                contentColor = Color.White
                            ),
                            onClick = {
                                handleStatus.value = StockHandleType.Line
                            },
                            modifier = Modifier.padding(8.dp),
                            elevation = ButtonDefaults.elevation()
                        ) {
                            Text(text = stringResource(R.string.btn_set_line))
                        }
                    }
                }

            }
        ) {
            Crossfade(handleStatus.value) { type->
                Surface() {
                    when(type){
                        StockHandleType.Detail -> StockDetailContent(vStock)
                        StockHandleType.Buy -> StockBuyContent(handleStatus, vStock)
                        StockHandleType.Sell -> StockSellContent(handleStatus, vStock)
                        StockHandleType.Bonus -> StockBonusContent(handleStatus, vStock)
                        StockHandleType.Line -> StockLineContent(mViewModel = mViewModel, handleStatus = handleStatus, vStock = vStock)
                    }
                }
            }
        }
    }

}

/**
 * 股票详情
 * 股票基本信息、日K线图、交易记录
 */
@Composable
fun StockDetailContent(vStock: Stock){

    val mViewModel: TradeViewModel = viewModel()
    val trades = mViewModel.trades.observeAsState(arrayListOf())
    mViewModel.getTrades(vStock.stockId, vStock.investIndex)

    val defaultDeleteState = TradeDeleteState(0L)
    val deleteTradeState = remember { mutableStateOf(defaultDeleteState)}

    if(deleteTradeState.value.id > 0){
        val resourceId = when(deleteTradeState.value.delType){
            "delete"->R.string.dialog_delete_trade
            "clear"->R.string.dialog_clear_stock
            else->R.string.dialog_frozen_trade
        }
        AlertDialog(
            text = {Text(stringResource(resourceId))},
            backgroundColor = Color.White,
            buttons = {
                Row(modifier = Modifier) {
                    TextButton(
                        onClick = { deleteTradeState.value = defaultDeleteState },
                        modifier = Modifier.padding(4.dp)
                    ) {
                        Text(text = stringResource(R.string.btn_cancel), color = Color.Gray)
                    }
                    TextButton(
                        onClick = {
                            if(deleteTradeState.value.delType == "delete"){
                                mViewModel.deleteTrade(vStock, deleteTradeState.value.id)
                            }else if(deleteTradeState.value.delType == "clear"){
                                mViewModel.clearTrade(vStock)
                            }
                            deleteTradeState.value = defaultDeleteState
                        },
                        modifier = Modifier.padding(4.dp)
                    ) {
                        Text(text = stringResource(R.string.btn_ok))
                    }
                }
            },
            onDismissRequest = {  deleteTradeState.value = defaultDeleteState  }
        )
    }

    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .padding(8.dp)
    ){
        item{
            StockBaseInfo(vStock = vStock)

            StockImage(vStock = vStock)

            Spacer(modifier = Modifier.height(15.dp))

            StockTrades(vStock = vStock, deleteTradeState, trades)

            Spacer(modifier = Modifier.height(50.dp))
        }
    }

}

/**
 * 股票基本信息
 * @param vStock 股票实体类
 *
 */
@Composable
fun StockBaseInfo(vStock: Stock){
    val context = LocalContext.current
    val strCaption = context.resources.getString(R.string.caption_stock)

    val profitColor = when{
        vStock.profitMoney==0F->Color.DarkGray
        vStock.profitMoney>0-> positiveColor
        else -> negativeColor
    }
    Row(){
        Text(String.format("%.2f", vStock.profitMoney), style = TextStyle(fontSize = 22.sp, color = profitColor), modifier = Modifier.align(Alignment.Bottom))
        Text("("+String.format("%.2f", vStock.profitRatio)+"%)", style = TextStyle(fontSize = 12.sp, color = profitColor), modifier = Modifier.align(Alignment.Bottom))
    }

    Row(modifier = Modifier.padding(top = 8.dp)){
        Text(stringResource(R.string.stock_hold), style = styleCaption, modifier = Modifier.weight(2f))
        Text(vStock.holdStock.toString(), style = styleBodyRight, modifier = Modifier.weight(3f))
        Text(stringResource(R.string.stock_profit), style = styleCaption, modifier = Modifier
            .weight(2f)
            .padding(start = 8.dp))
        Text(String.format("%.2f", vStock.totalProfit), style = styleBodyRight, modifier = Modifier.weight(3f))

    }
    Row(modifier = Modifier.padding(top = 8.dp)){
        Text(stringResource(R.string.stock_invest), style = styleCaption, modifier = Modifier.weight(2f))
        Text(String.format("%.2f", vStock.investMoney), style = styleBodyRight, modifier = Modifier.weight(3f))
        Text(strCaption+stringResource(R.string.stock_worth), style = styleCaption, modifier = Modifier
            .weight(2f)
            .padding(start = 8.dp))
        Text(String.format("%.2f", vStock.worthMoney), style = styleBodyRight, modifier = Modifier.weight(3f))
    }

    Row(modifier = Modifier.padding(top = 8.dp)){
        Text(stringResource(R.string.stock_cost), style = styleCaption, modifier = Modifier.weight(2f))
        Text(String.format("%.2f", vStock.costPrice), style = styleBodyRight, modifier = Modifier.weight(3f))
        Text(stringResource(R.string.stock_price), style = styleCaption, modifier = Modifier
            .weight(2f)
            .padding(start = 8.dp))
        Text(String.format("%.2f", vStock.stockPrice), style = styleBodyRight, modifier = Modifier.weight(3f))
    }

    Row(modifier = Modifier.padding(top = 8.dp)){
        Text(stringResource(R.string.stock_commission), style = styleCaption, modifier = Modifier.weight(2f))
        Text(String.format("%.2f", vStock.commissionMoney), style = styleBodyRight, modifier = Modifier.weight(3f))
        Text(stringResource(R.string.stock_transfer), style = styleCaption, modifier = Modifier
            .weight(2f)
            .padding(start = 8.dp))
        Text(String.format("%.2f", vStock.transferMoney), style = styleBodyRight, modifier = Modifier.weight(3f))
    }

    Row(modifier = Modifier.padding(top = 8.dp)){
        Text(stringResource(R.string.stock_stamp_tax), style = styleCaption, modifier = Modifier.weight(2f))
        Text(String.format("%.2f", vStock.taxMoney), style = styleBodyRight, modifier = Modifier.weight(3f))
        Text("", modifier = Modifier.weight(5f))
    }

    Row(modifier = Modifier.padding(top = 8.dp)){
        Text(strCaption+stringResource(R.string.stock_bonus), style = styleCaption, modifier = Modifier.weight(2f))
        Text(String.format("%.2f", vStock.bonusMoney), style = styleBodyRight, modifier = Modifier.weight(3f))
        Text(stringResource(R.string.stock_bonus_tax), style = styleCaption, modifier = Modifier
            .weight(2f)
            .padding(start = 8.dp))
        Text(String.format("%.2f", vStock.bonusTax), style = styleBodyRight, modifier = Modifier.weight(3f))
    }
    Row(modifier = Modifier.padding(top = 8.dp)){
        Text(stringResource(R.string.stock_buy_line), style = styleCaption, modifier = Modifier.weight(2f))
        Text(String.format("%.2f", vStock.buyLine), style = styleBodyRight, modifier = Modifier.weight(3f))
        Text(stringResource(R.string.stock_sell_line), style = styleCaption, modifier = Modifier
            .weight(2f)
            .padding(start = 8.dp))
        Text(String.format("%.2f", vStock.sellLine), style = styleBodyRight, modifier = Modifier.weight(3f))
    }
}

/**
 * 股票日K线图
 * @param vStock 股票实体类
 *
 */
@Composable
fun StockImage(vStock: Stock){
    val imageUrl = "https://image.sinajs.cn/newchart/daily/n/${vStock.stockExchange}${vStock.stockId}.gif"
    Row(modifier = Modifier.padding(vertical = 10.dp)){
        Box(modifier = Modifier.border(width = 1.dp, color = Color.LightGray)){
            Image(
                painter = rememberCoilPainter(request = imageUrl,),
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(8.dp),
                contentScale = ContentScale.Crop,
                contentDescription = "K线图"
            )
        }
    }
}

/**
 * 股票买入卖出记录
 * @param vStock 股票实体类
 * @param deleteTradeState 记录删除标志
 * @param trades 股票买卖记录
 *
 */
@SuppressLint("SimpleDateFormat")
@Composable
fun StockTrades(vStock: Stock, deleteTradeState: MutableState<TradeDeleteState>, trades: State<List<Trade>>){
    val formatDate = SimpleDateFormat("yyyy.MM.dd")
    val nowD = Calendar.getInstance().timeInMillis

    ListItemDivider()
    Row(
        modifier = Modifier.padding(vertical= 4.dp)
    ){
        Text(stringResource(id = R.string.text_date) + "/" + stringResource(id = R.string.text_price), style = styleHead, modifier = Modifier.weight(2f))
        Text(stringResource(id = R.string.text_amount), style = styleHead, modifier = Modifier.weight(1f))
        Text(stringResource(id = R.string.stock_gain) + "/" + stringResource(id = R.string.stock_days), style = styleHead, modifier = Modifier.weight(2f))
        Text(stringResource(id = R.string.stock_gain_ratio), style = styleHead, modifier = Modifier.weight(2f))
    }

    ListItemDivider()

    trades.value.forEach(){trade->
        val backColor = when{
            (deleteTradeState.value.id != -1L && trade.investIndex % 2 ==1) -> Color.White
            (deleteTradeState.value.id != -1L && trade.investIndex % 2 ==0) -> back001
            trade.status>=9 -> back013
            else -> Color.White
        }
        Row(
            verticalAlignment = Alignment.CenterVertically,
            modifier = Modifier
                .padding(vertical = 0.dp)
                .height(56.dp)
                .pointerInput(Unit) {
                    if (deleteTradeState.value.id != -1L) {
                        detectTapGestures(
                            onLongPress = { offset: Offset ->
                                val delType = when {
                                    trade.bonusId > 0 -> "clear"
                                    trade.status == 10 -> "no"
                                    else -> "delete"
                                }
                                deleteTradeState.value = TradeDeleteState(trade.id, delType)
                            }
                        )
                    }

                }
                .background(backColor)
        ){
            val date = Date(trade.buyDate)
            var sellPrice = vStock.stockPrice
            var sellDate = nowD
            var strPrices:String = String.format("%.2f", trade.buyPrice)
            if(trade.status>=9){
                sellPrice = trade.sellPrice
                sellDate = trade.sellDate
                strPrices += "-" + String.format("%.2f", sellPrice)
            }
            val gain = trade.stockAmount*(sellPrice - trade.buyPrice)
            var gainRatio = when(trade.buyPrice){
                0f->"空手套"
                else->String.format("%.2f", (sellPrice - trade.buyPrice)*100/trade.buyPrice)+"%"
            }
            val days = ((sellDate - trade.buyDate)/86400000).toInt()

            val styleProfit = if(vStock.stockPrice > trade.buyPrice) styleEarn else styleLose
            Column(modifier = Modifier.weight(2f), horizontalAlignment = Alignment.CenterHorizontally) {
                Text(text=formatDate.format(date), style = styleBody)
                Text(text=strPrices, style = styleLowerRight, modifier = Modifier.align(Alignment.CenterHorizontally))
            }
            Text(text=trade.stockAmount.toString(), style = styleBody, modifier = Modifier.weight(1f))
            Column(modifier = Modifier
                .weight(2f)
                .wrapContentWidth(Alignment.End)) {
                Text(text=String.format("%.2f", gain), style = styleProfit)
                Text(text=days.toString()+stringResource(id = R.string.unit_day), style = styleLowerRight, modifier = Modifier.align(Alignment.End))
            }
            Text(text=gainRatio, style = styleProfit, modifier = Modifier
                .weight(2f)
                .align(Alignment.CenterVertically))
        }
        ListItemDivider()
    }

}

/**
 * 股票设置页面
 * 设置买入和卖出提示
 * @param mViewModel 股票实体类
 * @param handleStatus 处理类型状态标志
 * @param vStock 股票实体类
 *
 */
@Composable
fun StockLineContent(mViewModel: StocksViewModel, handleStatus: MutableState<String>, vStock: Stock){
    val stocks = mViewModel.finished.observeAsState(false)
    val defaultBuy = when(vStock.buyLine){
        0f -> (vStock.stockPrice*0.9*100).toInt().toFloat()/100
        else -> vStock.buyLine
    }
    val defaultSell = when(vStock.sellLine){
        0f -> (vStock.stockPrice*1.1*100).toInt().toFloat()/100
        else -> vStock.sellLine
    }
    var buyLine by remember { mutableStateOf(TextFieldValue(text = defaultBuy.toString())) }
    var sellLine by remember { mutableStateOf(TextFieldValue(text = defaultSell.toString())) }
    val context = LocalContext.current

    if(stocks.value){
        handleStatus.value = StockHandleType.Detail
        mViewModel.finishReset()
    }else{
        LazyColumn(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp)
        ) {
            val strCaption = context.getResources().getString(R.string.text_price)
            item {
                InputItem(
                    textFieldValue = buyLine,
                    label = stringResource(id = R.string.stock_buy_line) + strCaption,
                    onTextChanged = { buyLine = it },
                    modifier = Modifier
                        .fillMaxSize()
                        .padding(vertical = 4.dp)
                )
            }
            item {
                InputItem(
                    textFieldValue = sellLine,
                    label = stringResource(id = R.string.stock_sell_line) + strCaption,
                    onTextChanged = { sellLine = it },
                    modifier = Modifier
                        .fillMaxSize()
                        .padding(vertical = 4.dp)
                )
            }
            item {
                Button(
                    onClick = {
                        mViewModel.stockSetup(vStock, buyLine.text.toFloat(), sellLine.text.toFloat())
                    },
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(vertical = 8.dp)
                ) {
                    Text(
                        text = stringResource(id = R.string.btn_set_line),
                        color = MaterialTheme.colors.onPrimary,
                        modifier = Modifier.padding(horizontal = 30.dp, vertical = 8.dp)
                    )
                }
            }
        }
    }


}
